package com.ldx.single;


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

//懒汉式单例
public class Lazyman {

    //标志位防止都是反射产生的实例对象破坏单例
    private static boolean singleFlag = false;


    private Lazyman() {
        synchronized (Lazyman.class) {
            if (singleFlag == false) {
                singleFlag = true;
            }
           else {
                throw new RuntimeException("不要试图反射破坏异常");
            }
        }
        System.out.println(Thread.currentThread().getName() + "OK");
    }

    private volatile  static Lazyman lazyman;

    //双重检测锁模式 懒汉式单例 DCL懒汉式
    public static Lazyman getInstance() {
        if (lazyman == null) {
            synchronized (Lazyman.class) {
                if (lazyman == null) {
                    lazyman = new Lazyman(); //不是一个原子性操作
                    /**
                     * 1.分配内存空间
                     * 2.执行构造器方法，初始化对象
                     * 3.把这个对象指向这个空间
                     *
                     * 123
                     * 132 A
                     *     B //此时lazyman还没有完成构造
                     */
                }
            }
        }
        return lazyman;
    }

    //反射
    public static void main(String[] args) throws Exception {
//        Lazyman instance = Lazyman.getInstance();
        Field singleFlag = Lazyman.class.getDeclaredField("singleFlag");
        singleFlag.setAccessible(true);

        Constructor<Lazyman> declaredConstructor = Lazyman.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        Lazyman instance = declaredConstructor.newInstance();

        singleFlag.set(instance,false);

        Lazyman instance2 = declaredConstructor.newInstance();

        System.out.println(instance);
        System.out.println(instance2);//反射破坏单例模式
    }
}
